package edu.zju.udms.dnavigator.core.server;

import java.io.File;
import java.net.URL;

import org.apache.log4j.Logger;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.security.Credential;
import org.eclipse.jetty.webapp.WebAppContext;

import edu.zju.udms.dnavigator.core.config.Configuration;
import edu.zju.udms.dnavigator.core.repository.Repository;
import edu.zju.udms.dnavigator.core.utils.FileUtils;

public class WebService {
	private final Logger logger=Logger.getLogger(WebService.class);
	private final String servletPackageName="edu.zju.udms.dnavigator.core.server.servlets."; 
	private final String[][] servletMapping={
		{"EntitySearchServlet","/entity/search/*"},
		{"EntityDetailServlet","/entity/detail/*"},
		{"EntitySchemaServlet","/entity/schema/*"},
		{"EntityGlobalLineageServlet","/entity/globallineage"},
		{"ApiSourceServlet", "/api/source/*"},
		{"ApiAdminServlet", "/api/admin"},
		{"ApiSystemServlet", "/api/system"},
		{"ApiAgentServlet", "/api/agent"},
	};
			
	Server server;
	WebAppContext webapp;
	Configuration configuration;
	Repository repository;
	
	public WebService(Configuration configuration,Repository repository) throws Exception {
		this.configuration=configuration;
		this.repository=repository;
		int port = Integer.parseInt(configuration.getProperty("webserver.port"));
		server=new Server(port);
		WebAppContext webapp = new WebAppContext();
		File webDir=new File("./WebContent/");
		if(webDir.exists()){
			webDir.delete();
			logger.info("expired web content removed");
		}
		URL webContentUrl = WebService.class.getResource("/WebContent");
		logger.debug("web content url :"+webContentUrl.toString());
		if(webContentUrl.toString().startsWith("jar")){
			//jar
			webDir.mkdir();
			FileUtils.copyResourcesRecursively(webContentUrl, webDir);
		}else{
			FileUtils.copyResourcesRecursively(webContentUrl, new File("."));
		}
		logger.info("web content copy finish");
		webapp.setResourceBase("WebContent");
		webapp.setContextPath("/");
		webapp.getServletContext().setAttribute("repository", this.repository);
		webapp.getServletContext().setAttribute("config", this.configuration);
		server.setHandler(webapp);

		HashLoginService loginService = new HashLoginService();
		loginService.setName("D-Meta password");
		loginService.putUser("dmeta", Credential.getCredential(configuration.getProperty("dmeta.password")), new String[]{"user"});
		Constraint constraint = new Constraint();
        constraint.setName(Constraint.__BASIC_AUTH);
        constraint.setRoles(new String[]{"user"});
        constraint.setAuthenticate(true);
         
        ConstraintMapping cm = new ConstraintMapping();
        cm.setConstraint(constraint);
        cm.setPathSpec("/*");
        
        ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
        csh.setAuthenticator(new BasicAuthenticator());
        csh.setRealmName("realm");
        csh.addConstraintMapping(cm);
        csh.setLoginService(loginService);
        webapp.setSecurityHandler(csh);
		for(String[] entry:servletMapping){
			if(entry.length < 2)
				continue;
			webapp.addServlet(servletPackageName+entry[0], entry[1]);
		}
	}
	
	public void service() throws Exception{
		server.start();
	}
	
	public void stop() throws Exception{
		server.stop();
	}
	
}
